<template>
  <div>
    <Form
      :model="formValidate"
      ref="formValidate"
      :rules="ruleValidate"
      :label-width="80"
    >
      <FormItem label="标题" prop="title">
        <Input v-model="formValidate.title" placeholder="请填写标题（最多20字）"></Input>
      </FormItem>
      <FormItem label="正文" prop="content">
        <Input
          type="textarea"
          :autosize="{ minRows: 5, maxRows: 10 }"
          v-model="formValidate.content"
          placeholder="请输入正文"
        ></Input>
      </FormItem>
      <FormItem label="上传视频" prop="url">
        <Upload
          v-show="!formValidate.url"
          action
          accept="video/mp4, video/avi"
          :format="['mp4', 'avi']"
          :before-upload="beforeUpload"
        >
          <Button v-if="videoFlag" loading>{{ videoLabel }}</Button>
          <div v-else class="uploadBox">
            <img src="@/assets/active/upload.png" />
          </div>
        </Upload>
        <Progress
          v-if="videoFlag"
          style="width: 200px; margin-left: 10px"
          :percent="process"
          status="active"
        />
        <div v-show="formValidate.url" class="videoBox">
          <video controls class="videoEL" :src="formValidate.url"></video>
          <img
            src="@/assets/active/del.png"
            @click="formValidate.url = ''"
            class="delImg"
          />
        </div>
      </FormItem>
      <FormItem>
        <Button @click="handleReturn">返回</Button>
        <Button
          type="error"
          style="margin-left: 8px"
          @click="handleSubmit('formValidate')"
          >提交</Button
        >
      </FormItem>
    </Form>
  </div>
</template>

<script>
import { joinActive } from "@/api/community";
import storage from "@/plugins/storage.js";

import md5 from "@/utils/spark-md5";
import { verifyFile, initTask, preSignUrl, mergeChunks } from "@/api/chunkFile";
let chunkSize = 1024 * 1024 * 5; //分片大小

export default {
  props: {},
  components: {},
  data() {
    return {
      formValidate: {
        title: "",
        content: "",
        url: "",
      },
      ruleValidate: {
        title: [
          { required: true, message: "请输入标题", trigger: "change" },
          {
            type: "string",
            max: 20,
            message: "最多输入20字",
            trigger: "change",
          },
        ],
        content: [{ required: true, message: "请输入正文", trigger: "change" }],
        url: [{ required: true, message: "请选择视频", trigger: "change" }],
      },
      mid: JSON.parse(localStorage.userInfo).id,
      title: "",
      content: "",
      activeId: "",
      accessToken: {}, // 验证token
      videoFlag: false,
      chunksList: [], // 用户选中文件的切片文件
      current: 0, //进度
      videoLabel: "上传",
    };
  },
  mounted() {
    this.activeId = this.$route.query.id;
    this.accessToken.accessToken = storage.getItem("accessToken");
  },
  computed: {
    process: {
      get() {
        let z = this.current;
        let m = this.chunksList.length || 1;
        let r = (parseFloat(z / m) * 100).toFixed(2);
        return parseFloat(r);
      },
      set() {},
    },
  },
  methods: {
    async getTaskInfo(file) {
      let task = null;
      let identifier = await md5(file);
      this.videoLabel = "检查中";
      const { code, data } = await verifyFile(identifier);
      if (code == 200000) {
        task = data;
        if (!task) {
          const initTaskData = {
            identifier,
            fileName: file.name,
            totalSize: file.size,
            chunkSize,
          };
          const res = await initTask(initTaskData);
          if (res.code == 200000) {
            task = res.data;
          } else {
            this.videoFlag = false;
            this.$Message.warning(res.msg);
          }
        } else {
          this.videoFlag = false;
        }
      }
      return task;
    },
    // 分片上传
    async handleUpload(file, taskRecord) {
      let start = 0; // 切片文件的起始位置
      while (start < file.size) {
        const chunkItem = file.slice(start, start + chunkSize);
        this.chunksList.push(chunkItem);
        start += chunkSize;
      }
      let identifier = taskRecord.fileIdentifier;
      let requestList = [];
      for (let i = 0; i < taskRecord.chunkNum; i++) {
        requestList.push(preSignUrl(this.chunksList, identifier, i + 1));
      }
      requestList.map((item) => {
        item.then(() => {
          this.current++;
        });
      });
      // 等待所有切片上传完成
      await Promise.all(requestList);
      this.videoLabel = "合并中";
      mergeChunks(identifier)
        .then((result) => {
          if (result.code == 200) {
            this.formValidate.url = result.result.location;
            this.chunksList = [];
          }
        })
        .finally(() => {
          this.videoFlag = false;
          this.videoLabel = "上传";
          this.current = 0;
        });
    },
    // 自定义上传视频
    beforeUpload(file) {
      let typeList = [".mp4", ".avi"];
      if (!typeList.some((i) => file.name.lastIndexOf(i) != -1)) {
        this.$Message.warning("请检查上传视频格式");
        return;
      }
      if (file.size / 1024 > 2 * 1024 * 1024) {
        this.$Message.warning("视频大小不能超过2GB");
        return;
      }
      this.handleMaxVideo(file);
      return false;
    },
    // 大文件视频上传
    async handleMaxVideo(file) {
      this.videoFlag = true;
      this.videoLabel = "准备中";
      const task = await this.getTaskInfo(file);
      this.videoLabel = "上传中";
      if (task) {
        const { finished, path, taskRecord } = task;
        if (finished) {
          this.formValidate.url = path;
          this.videoFlag = false;
          this.videoLabel = "上传";
          this.current = 0;
        } else {
          await this.handleUpload(file, taskRecord);
        }
      } else {
        this.videoFlag = false;
        this.videoLabel = "上传";
        this.$Massage.warning("上传失败");
        this.current = 0;
      }
    },
    handleReturn() {
      this.$router.go(-1);
    },
    handleSubmit(name) {
      this.$refs[name].validate((valid) => {
        if (valid) {
          let data = {
            type: 2,
            mid: this.mid,
            act_id: this.activeId,
            video_url: this.formValidate.url,
            title: this.formValidate.title,
            content: this.formValidate.content,
          };
          joinActive(data).then((res) => {
            if (res.code == 1) {
              this.$Message.success("报名成功");
              this.handleReturn();
            }
          });
        } else {
          this.$Message.error("请输入必填参数");
        }
      });
    },
  },
};
</script>

<style scoped lang="scss">
.uploadBox {
  width: 104px;
  height: 104px;
  border: 1px solid #e3e2e2;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;

  img {
    width: 31px;
    height: 31px;
  }
}
.ivu-upload {
  display: inline-block;
}
.videoBox {
  .videoEL {
    width: 60%;
    position: relative;
  }
  .delImg {
    cursor: pointer;
    width: 31px;
    height: 31px;
    position: absolute;
    right: 38%;
    top: -10px;
  }
}
</style>
